#include <SDL2/SDL.h>
#include <SDL2/SDL_pixels.h>
#include <freetype2/ft2build.h>
#include FT_FREETYPE_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <stdbool.h>  // Add stdbool.h

typedef struct {
    char file_path[1024];
    char url[1024];
    char geometry[32];
    bool keep_cache;
} Config;

typedef struct {
    SDL_Rect rect;
    const char* label;
    bool hovered;
    bool pressed;
} Button;

typedef struct {
    SDL_Rect rect;
    char* text;
    int max_len;
    bool focused;
    const char* label;
} InputBox;

static SDL_Window* window;
static SDL_Renderer* renderer;
static FT_Library ft_lib;
static FT_Face ft_face;
static Config cfg;
static Button btn_browse, btn_play, btn_clean, btn_help;
static InputBox input_file, input_url, input_geometry;
static bool show_help = false;
static const char* help_text = 
    "Usage:\n"
    "  - Select local file or enter URL (choose one)\n"
    "  - Window geometry: widthxheight+X+Y (default 1920x1080+0+0)\n"
    "  - Keep cache: Reuse cache for same URL\n"
    "  - Clean cache: Delete all cached files\n"
    "  - Press ESC to close help";

int init_sdl() {
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        fprintf(stderr, "SDL init failed: %s\n", SDL_GetError());
        return -1;
    }
    window = SDL_CreateWindow("Video Desktop Player", 
                             SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
                             600, 400, 0);
    if (!window) {
        fprintf(stderr, "Window create failed: %s\n", SDL_GetError());
        return -1;
    }
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (!renderer) {
        fprintf(stderr, "Renderer create failed: %s\n", SDL_GetError());
        SDL_DestroyWindow(window);
        return -1;
    }
    return 0;
}

int init_freetype() {
    if (FT_Init_FreeType(&ft_lib) != 0) {
        fprintf(stderr, "FreeType init failed\n");
        return -1;
    }

    // Use YOUR Liberation Sans Regular font (matches your ls output)
    const char* font_paths[] = {
        "/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf",
        "/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf",  // Fallback
        "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"
    };

    for (size_t i = 0; i < sizeof(font_paths)/sizeof(font_paths[0]); i++) {
        if (FT_New_Face(ft_lib, font_paths[i], 0, &ft_face) == 0) {
            FT_Set_Pixel_Sizes(ft_face, 0, 16);  // 16px height
            return 0;
        }
    }

    fprintf(stderr, "No font found\n");
    FT_Done_FreeType(ft_lib);
    return -1;
}

void init_gui() {
    memset(cfg.file_path, 0, 1024);
    memset(cfg.url, 0, 1024);
    strcpy(cfg.geometry, "1920x1080+0+0");
    cfg.keep_cache = false;

    input_file = (InputBox){
        {50, 80, 400, 30}, cfg.file_path, 1023, false, "Local File:"
    };
    input_url = (InputBox){
        {50, 140, 400, 30}, cfg.url, 1023, false, "URL:"
    };
    input_geometry = (InputBox){
        {50, 200, 200, 30}, cfg.geometry, 31, false, "Window Geometry:"
    };

    btn_browse = (Button){{470, 80, 80, 30}, "Browse...", false, false};
    btn_play = (Button){{50, 320, 120, 40}, "Play", false, false};
    btn_clean = (Button){{200, 320, 120, 40}, "Clean Cache", false, false};
    btn_help = (Button){{350, 320, 120, 40}, "Help", false, false};
}

// Fixed text rendering (properly handle 8-bit grayscale from FreeType)
void draw_text(const char* text, int x, int y, SDL_Color color) {
    if (!text || !*text || !ft_face) return;

    FT_GlyphSlot slot = ft_face->glyph;
    int pen_x = x, pen_y = y;

    for (size_t i = 0; text[i]; i++) {
        if (FT_Load_Char(ft_face, text[i], FT_LOAD_RENDER) != 0) continue;

        // Create 8-bit grayscale surface with correct palette
        SDL_Surface* surf = SDL_CreateRGBSurfaceFrom(
            slot->bitmap.buffer,
            slot->bitmap.width,
            slot->bitmap.rows,
            8,  // 8 bits per pixel (grayscale)
            slot->bitmap.pitch,
            0x000000ff,  // Red mask (8-bit)
            0x0000ff00,  // Green mask
            0x00ff0000,  // Blue mask
            0xff000000   // Alpha mask (unused)
        );
        if (!surf) {
            fprintf(stderr, "Surface create failed: %s\n", SDL_GetError());
            continue;
        }

        // Convert to RGBA for proper rendering
        SDL_Surface* rgba_surf = SDL_ConvertSurfaceFormat(surf, SDL_PIXELFORMAT_RGBA8888, 0);
        SDL_FreeSurface(surf);
        if (!rgba_surf) continue;

        // Apply text color (tint the grayscale)
        Uint32* pixels = (Uint32*)rgba_surf->pixels;
        int total = rgba_surf->w * rgba_surf->h;
        for (int j = 0; j < total; j++) {
            Uint8 gray = (pixels[j] & 0xff);  // Extract grayscale value
            pixels[j] = (gray << 24) | (color.r << 16) | (color.g << 8) | color.b;
        }

        SDL_Texture* tex = SDL_CreateTextureFromSurface(renderer, rgba_surf);
        if (tex) {
            SDL_Rect dst = {
                pen_x + slot->bitmap_left,
                pen_y - slot->bitmap_top,
                rgba_surf->w,
                rgba_surf->h
            };
            SDL_RenderCopy(renderer, tex, NULL, &dst);
            SDL_DestroyTexture(tex);
        }
        SDL_FreeSurface(rgba_surf);

        pen_x += slot->advance.x >> 6;  // Move to next character
    }
}

unsigned int get_text_width(const char* text) {
    if (!text || !*text || !ft_face) return 0;

    unsigned int width = 0;
    FT_GlyphSlot slot = ft_face->glyph;
    for (size_t i = 0; text[i]; i++) {
        if (FT_Load_Char(ft_face, text[i], FT_LOAD_RENDER) != 0) continue;
        width += slot->advance.x >> 6;
    }
    return width;
}

void draw_input_box(InputBox* box) {
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    SDL_RenderFillRect(renderer, &box->rect);

    SDL_SetRenderDrawColor(renderer, box->focused ? 255 : 0, 0, 0, 255);
    SDL_RenderDrawRect(renderer, &box->rect);

    draw_text(box->label, box->rect.x, box->rect.y - 20, (SDL_Color){0, 0, 0, 255});
    draw_text(box->text, box->rect.x + 5, box->rect.y + 5, (SDL_Color){0, 0, 0, 255});

    if (box->focused) {
        unsigned int len = get_text_width(box->text);
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        SDL_RenderDrawLine(renderer,
            box->rect.x + 5 + len, box->rect.y + 5,
            box->rect.x + 5 + len, box->rect.y + 25
        );
    }
}

void draw_button(Button* btn) {
    SDL_Color bg = {255, 255, 255, 255};
    if (btn->pressed) bg = (SDL_Color){136, 136, 136, 255};
    else if (btn->hovered) bg = (SDL_Color){238, 238, 238, 255};

    SDL_SetRenderDrawColor(renderer, bg.r, bg.g, bg.b, bg.a);
    SDL_RenderFillRect(renderer, &btn->rect);

    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderDrawRect(renderer, &btn->rect);

    unsigned int len = get_text_width(btn->label);
    int tx = btn->rect.x + (btn->rect.w - len)/2;
    int ty = btn->rect.y + (btn->rect.h + 8)/2;
    draw_text(btn->label, tx, ty, (SDL_Color){0, 0, 0, 255});
}

void handle_input(InputBox* box, SDL_Event* ev) {
    if (!box->focused || ev->type != SDL_KEYDOWN) return;

    SDL_Keycode key = ev->key.keysym.sym;
    if (key == SDLK_BACKSPACE && strlen(box->text) > 0) {
        box->text[strlen(box->text)-1] = '\0';
    } else if (key >= 32 && key <= 126) {
        size_t len = strlen(box->text);
        if (len < box->max_len) {
            box->text[len] = (char)key;
            box->text[len+1] = '\0';
        }
    }
}

void open_file_dialog() {
    FILE* pipe = popen("zenity --file-selection --title='Select Video File'", "r");
    if (!pipe) return;

    char path[1024];
    if (fgets(path, sizeof(path), pipe)) {
        path[strcspn(path, "\n")] = '\0';
        strncpy(cfg.file_path, path, sizeof(cfg.file_path)-1);
    }
    pclose(pipe);
}

void run_cli() {
    char cmd[4096] = "./peruere ";
    size_t len = strlen(cmd);

    if ((strlen(cfg.file_path) == 0 && strlen(cfg.url) == 0) ||
        (strlen(cfg.file_path) > 0 && strlen(cfg.url) > 0)) {
        fprintf(stderr, "Select local file or URL (choose one)\n");
        return;
    }

    if (strlen(cfg.file_path) > 0) {
        snprintf(cmd + len, sizeof(cmd) - len, "--file \"%s\" ", cfg.file_path);
        len = strlen(cmd);
    }
    if (strlen(cfg.url) > 0) {
        snprintf(cmd + len, sizeof(cmd) - len, "--url \"%s\" ", cfg.url);
        len = strlen(cmd);
    }
    snprintf(cmd + len, sizeof(cmd) - len, "--geometry %s ", cfg.geometry);
    len = strlen(cmd);
    if (cfg.keep_cache) {
        strncat(cmd, "--keep", sizeof(cmd) - len - 1);
    }

    system(cmd);
}

void redraw() {
    SDL_SetRenderDrawColor(renderer, 240, 240, 240, 255);
    SDL_RenderClear(renderer);

    draw_text("Video Desktop Player", 200, 40, (SDL_Color){85, 85, 85, 255});

    draw_input_box(&input_file);
    draw_input_box(&input_url);
    draw_input_box(&input_geometry);

    draw_button(&btn_browse);
    draw_button(&btn_play);
    draw_button(&btn_clean);
    draw_button(&btn_help);

    SDL_Rect checkbox = {50, 260, 20, 20};
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderDrawRect(renderer, &checkbox);
    if (cfg.keep_cache) {
        SDL_RenderFillRect(renderer, &(SDL_Rect){52, 262, 16, 16});
    }
    draw_text("Keep Cache (-k)", 80, 280, (SDL_Color){0, 0, 0, 255});

    if (show_help) {
        SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
        SDL_RenderFillRect(renderer, &(SDL_Rect){50, 50, 500, 300});
        SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
        SDL_RenderDrawRect(renderer, &(SDL_Rect){50, 50, 500, 300});

        char buf[1024];
        strncpy(buf, help_text, sizeof(buf)-1);
        char* line = strtok(buf, "\n");
        int y = 70;
        while (line) {
            draw_text(line, 70, y, (SDL_Color){0, 0, 0, 255});
            y += 20;
            line = strtok(NULL, "\n");
        }
    }

    SDL_RenderPresent(renderer);
}

int main() {
    if (init_sdl() != 0) return 1;
    if (init_freetype() != 0) {
        SDL_DestroyRenderer(renderer);
        SDL_DestroyWindow(window);
        SDL_Quit();
        return 1;
    }

    init_gui();
    bool running = true;
    SDL_Event ev;

    while (running) {
        while (SDL_PollEvent(&ev)) {
            if (ev.type == SDL_QUIT) {
                running = false;
                break;
            }

            if (ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_ESCAPE) {
                if (show_help) show_help = false;
                else running = false;
                break;
            }

            int x, y;
            SDL_GetMouseState(&x, &y);
            btn_browse.hovered = SDL_PointInRect(&(SDL_Point){x, y}, &btn_browse.rect);
            btn_play.hovered = SDL_PointInRect(&(SDL_Point){x, y}, &btn_play.rect);
            btn_clean.hovered = SDL_PointInRect(&(SDL_Point){x, y}, &btn_clean.rect);
            btn_help.hovered = SDL_PointInRect(&(SDL_Point){x, y}, &btn_help.rect);

            if (ev.type == SDL_MOUSEBUTTONDOWN) {
                input_file.focused = SDL_PointInRect(&(SDL_Point){x, y}, &input_file.rect);
                input_url.focused = SDL_PointInRect(&(SDL_Point){x, y}, &input_url.rect);
                input_geometry.focused = SDL_PointInRect(&(SDL_Point){x, y}, &input_geometry.rect);

                if (btn_browse.hovered) { btn_browse.pressed = true; open_file_dialog(); }
                if (btn_play.hovered) { btn_play.pressed = true; run_cli(); }
                if (btn_clean.hovered) { btn_clean.pressed = true; system("./peruere --clean-cache"); }
                if (btn_help.hovered) { btn_help.pressed = true; show_help = !show_help; }

                if (SDL_PointInRect(&(SDL_Point){x, y}, &(SDL_Rect){50, 260, 20, 20})) {
                    cfg.keep_cache = !cfg.keep_cache;
                }
            }

            if (ev.type == SDL_MOUSEBUTTONUP) {
                btn_browse.pressed = false;
                btn_play.pressed = false;
                btn_clean.pressed = false;
                btn_help.pressed = false;
            }

            handle_input(&input_file, &ev);
            handle_input(&input_url, &ev);
            handle_input(&input_geometry, &ev);
        }

        redraw();
    }

    FT_Done_Face(ft_face);
    FT_Done_FreeType(ft_lib);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}
